package com.yunxi.service.dubboService.impl.sto;

import com.alibaba.cloud.context.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.yunxi.core.util.BeanTools;
import com.yunxi.dealer.pojo.PartnerVO;
import com.yunxi.model.order.PmsVehicleStock;
import com.yunxi.model.sto.StoChangeStorage;
import com.yunxi.model.sto.StoManage;
import com.yunxi.model.sto.VehicleOffline;
import com.yunxi.service.localService.CodeCreateService;
import com.yunxi.service.localService.VehicleStockService;
import com.yunxi.service.localService.sto.StoChangeStorageService;
import com.yunxi.service.localService.sto.StoManageService;
import com.yunxi.service.localService.sto.VehicleOfflineService;
import com.yunxi.service.localService.sto.VehicleStockMService;
import com.yunxi.sto.pojo.*;
import com.yunxi.sto.service.StoChangeStorageDubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * <p>
 * 车辆移库单 服务实现类
 * </p>
 *
 * @author caoYong
 * @since 2019-05-28
 */
public class StoChangeStorageDubboServiceImpl implements StoChangeStorageDubboService {

    @Autowired
    @Qualifier(value = "stoChangeStorageServiceImpl")
    StoChangeStorageService stoChangeStorageService;

    @Autowired
    @Qualifier(value = "codeCreateServiceImpl")
    CodeCreateService codeCreateService;

    @Autowired
    @Qualifier(value = "stoManageServiceImpl")
    StoManageService stoManageService;

    @Autowired
    @Qualifier(value = "vehicleStockServiceImpl")
    VehicleStockService vehicleStockService;

    @Autowired
    @Qualifier(value = "vehicleOfflineServiceImpl")
    VehicleOfflineService vehicleOfflineService;

    @Autowired
    @Qualifier(value = "vehicleStockMServiceImpl")
    VehicleStockMService vehicleStockMService;


    @Override
    public StoChangeStorageVO getById(String id)throws Exception {
        StoChangeStorageVO vo = stoChangeStorageService.getInfoById(id);
        if(vo == null)throw new Exception("操作失败,无法根据主键:"+id+"找到对应记录!");
        return vo;
    }

    @Override
    public void saveOrUpdate(StoChangeStorageEditVO stoChangeStorageEditVO) throws Exception {
        StoChangeStorage stoChangeStorage = new StoChangeStorage();
        BeanTools.copyProperties(stoChangeStorage,stoChangeStorageEditVO);
        String oldTargetStorageCode = null;
        String oldVin = null;
        String newVin = stoChangeStorageEditVO.getVin();
        String newTargetStorageCode = stoChangeStorageEditVO.getNewStorageCode();
        if(stoChangeStorage.getChangeStorageId() == null){
            String scs = codeCreateService.createCode("SCS", 4);
            stoChangeStorage.setChangeStorageNo(scs);
            stoChangeStorage.setBillState("0");
        }
        else{
            //移库中的单据不允许编辑
            StoChangeStorage byId = stoChangeStorageService.getById(stoChangeStorage.getChangeStorageId());
            oldVin = byId.getVin();
            String billState = byId.getBillState();
            oldTargetStorageCode = byId.getNewStorageCode();
            if(billState != null && !billState.equals("0")){
                throw new Exception("操作失败,只能编辑新建的移库单!");
            }
        }
        //新增或编辑,校验该VIN是否已存在未完成的移库单
        Boolean aBoolean = stoChangeStorageService.queryIsExsit(stoChangeStorageEditVO);
        if(aBoolean){
            throw new Exception("操作失败,车辆"+stoChangeStorageEditVO.getVin()+"已存在未完成的移库单!");
        }
        //冻结选择的目标库位
        frozenTargetStorageCode(oldTargetStorageCode, newTargetStorageCode);
        //设置所属仓库名
        String storageFullName = stoManageService.getStorageFullName(stoChangeStorageEditVO.getOldStorageCode());
        if(StringUtils.isNotEmpty(storageFullName)){
            String[] split = storageFullName.split("-");
            stoChangeStorage.setStorageName(split[0]);
        }
        stoChangeStorageService.saveOrUpdate(stoChangeStorage);
        //锁定/解锁VIN
        lockVin(newVin,1);
        if(oldVin != null && !oldVin.equals(newVin)){
            lockVin(oldVin,0);
        }
    }

    private void lockVin(String newVin,Integer isLock) throws Exception{
        if(isLock == null)throw new Exception("操作失败,请选择是否冻结!");
        QueryWrapper<VehicleOffline> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("VIN",newVin);
        VehicleOffline vehicleOffline = vehicleOfflineService.getOne(queryWrapper);
        if(vehicleOffline != null){
            vehicleOffline.setVehicleIsFrozen(isLock);
            vehicleOfflineService.saveOrUpdate(vehicleOffline);
        }
        QueryWrapper<PmsVehicleStock> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("VIN",newVin);
        PmsVehicleStock one = vehicleStockMService.getOne(queryWrapper1);
        if(one != null){
            one.setVehicleIsFrozen(isLock.toString());
            vehicleStockMService.saveOrUpdate(one);
            VehicleStockFrozenVO vehicleStockFrozenVO = new VehicleStockFrozenVO();
            //新增冻结解冻历史
            vehicleStockFrozenVO.setFrozenReason("车辆移库");
            vehicleStockMService.newFrozenHis(isLock.toString(),vehicleStockFrozenVO,newVin,2);
        }
    }

    /**
     * 冻结编辑后选择的目标库位,解冻之前选择目标库位
     * @param oldTargetStorageCode 旧目标库位
     * @param newTargetStorageCode 新目标库位
     */
    private void frozenTargetStorageCode(String oldTargetStorageCode, String newTargetStorageCode){
        if(oldTargetStorageCode != null){
            QueryWrapper<StoManage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("STORAGE_CODE",oldTargetStorageCode);
            StoManage one = stoManageService.getOne(queryWrapper);
            if(one != null){
                one.setIsPositionFrozen(0);
                stoManageService.updateById(one);//解冻之前的目标库位
                //插入解冻历史
                vehicleStockMService.newFrozenHis("0",null,one.getStorageCode(),1);
            }

        }
        QueryWrapper<StoManage> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("STORAGE_CODE",newTargetStorageCode);
        StoManage two = stoManageService.getOne(queryWrapper2);
        if(two != null){
            two.setIsPositionFrozen(1);//冻结新选择的目标库位
            stoManageService.updateById(two);
            //插入冻结历史
            vehicleStockMService.newFrozenHis("1",null,two.getStorageCode(),1);
        }
    }

    @Override
    public void removeById(String id) {
    stoChangeStorageService.removeById(id);
    }

    @Override
    public PageInfo<StoChangeStorageQueryVO> findPageByVO(StoChangeStorageQueryVO stoChangeStorageQueryVO, Integer pageNum, Integer pageSize) {
        PageInfo<StoChangeStorageQueryVO> pageInfo = stoChangeStorageService.pageByVo(stoChangeStorageQueryVO, pageNum, pageSize);
        return pageInfo;
    }

    @Override
    public void removeByListVo(List<StoChangeStorageVO> stoChangeStorageVOList) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        stoChangeStorageService.removeByListVo(stoChangeStorageVOList);
    }

    /**
     * 获取在库车辆
     */
    @Override
    public List vinList(PartnerVO vo) {
        return stoChangeStorageService.vinList(vo);
    }

    /**
     * 获取空闲库位
     * @return list
     */
    @Override
    public List storageList() {
        return stoChangeStorageService.storageList(null);
    }

    /**
     * 作废
     * @param list 主键id集合
     */
    @Override
    public void delByList(List<String> list,String billState,String userId)throws Exception {
        stoChangeStorageService.delByList(list,billState,userId);
        //作废单据,则解锁所选VIN
        if(billState.equals("3")){
            for (String id :list){
                StoChangeStorage stoChangeStorage = stoChangeStorageService.getById(id);
                if(stoChangeStorage != null){
                    lockVin(stoChangeStorage.getVin(),0);
                }
            }
        }
    }

    @Override
    public StoChangeStorageVehicleInfoVO pdaVehicleInfo(String vin)throws Exception {
        return stoChangeStorageService.pdaVehicleInfo(vin);
    }

    /**
     * 开始移库
     * @param stoStockScanVO 移库信息
     */
    @Override
    public void startChange(StoStockScanVO stoStockScanVO) throws Exception{
        stoChangeStorageService.startChange(stoStockScanVO);
    }

    /**
     * 完成移库
     * @param stoStockScanVO 移库信息
     */
    @Override
    public void complete(StoStockScanVO stoStockScanVO) throws Exception{
        stoChangeStorageService.complete(stoStockScanVO);
    }

    /**
     * 导入批量新增移库
     * @param list
     * @throws Exception
     */
    @Override
    public void importBatch(List<StoChangeStorageImportVO> list) throws Exception {
        if(list != null && list.size() > 0){
            for (StoChangeStorageImportVO vo : list){
                //1.校验该VIN是否已存在未完成的移库单
                StoChangeStorageEditVO stoChangeStorageEditVO = new StoChangeStorageEditVO();
                stoChangeStorageEditVO.setVin(vo.getVin());
                Boolean aBoolean = stoChangeStorageService.queryIsExsit(stoChangeStorageEditVO);
                if(aBoolean){
                    throw new Exception("操作失败,车辆"+stoChangeStorageEditVO.getVin()+"已存在未完成的移库单!");
                }
                //2.查询该vin对应旧库位信息
                QueryWrapper<PmsVehicleStock> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("VIN",vo.getVin());
                PmsVehicleStock vehicleStock = vehicleStockService.getOne(queryWrapper);
                if(vehicleStock == null)throw new Exception("操作失败,VIN码:"+vo.getVin()+"不存在!");

                StoChangeStorage stoChangeStorage = new StoChangeStorage();
                stoChangeStorage.setVin(vo.getVin());
                stoChangeStorage.setBillState("0");
                String scs = codeCreateService.createCode("SCS", 4);
                stoChangeStorage.setChangeStorageNo(scs);
                stoChangeStorage.setOldStorageCode(vehicleStock.getStorageLocation());
                //3.查询目标库位代码,检查是否被占用,冻结
                String ck = vo.getNewStorageStoreName().replaceAll("\\s*", "");//仓库名
                String kq = vo.getNewStorageAreaName().replaceAll("\\s*", "");//库区名
                String kd = vo.getNewStorageLoadName().replaceAll("\\s*", "");//库道名
                String kw = vo.getNewStorageName().replaceAll("\\s*", "");//库位名
                if(StringUtils.isEmpty(ck) || StringUtils.isEmpty(kq) || StringUtils.isEmpty(kd) || StringUtils.isEmpty(kw)){
                    throw new Exception("操作失败,仓库/库区/库道/库位名称为空!");
                }
                String storageFullName = ck+"-"+kq+"-"+kd+"-"+kw;
                QueryWrapper<StoManage> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("STORAGE_FULL_NAME", storageFullName);
                StoManage stoManage = stoManageService.getOne(queryWrapper1);
                if(stoManage == null)throw new Exception("操作失败,库位:"+storageFullName+"不存在!");
                Integer isPositionFrozen = stoManage.getIsPositionFrozen();//是否冻结
                String storagePositionState = stoManage.getStoragePositionState();//是否占用
                if((isPositionFrozen != null && isPositionFrozen.equals(1)) || (StringUtils.isNotEmpty(storagePositionState) && storagePositionState.equals("2"))){
                    throw new Exception("操作失败,库位:"+storageFullName+"已被占用或冻结!");
                }
                stoChangeStorage.setNewStorageCode(stoManage.getStorageCode());
                stoChangeStorage.setChangeReason(vo.getChangeReason());
                stoChangeStorageService.saveOrUpdate(stoChangeStorage);
            }
        }
        else{
            throw new Exception("操作失败,导入数据为空!");
        }
    }

    /**
     * 根据VIN查询移库计划
     * @param vin
     * @return
     * @throws Exception
     */
    @Override
    public List<StoChangeStorageVO> planListByVin(String vin) throws Exception {
        return stoChangeStorageService.planListByVin(vin);
    }

    /**
     * 导出
     * @param stoChangeStorageQueryVO
     * @return
     */
    @Override
    public List<StoChangeStorageExportVO> exportList(StoChangeStorageQueryVO stoChangeStorageQueryVO) {
        return stoChangeStorageService.exportList(stoChangeStorageQueryVO);
    }
}
